/** Element Plus 组件全局配置 */

import { ElDialog, ElForm, ElInput, ElInputNumber, ElMessageBox, ElSelect, ElTable, ElTree, ElTreeSelect } from "element-plus";
import { isString } from "lodash-unified";
import type { ElMessageBoxOptions, MessageBoxData, TableProps } from "element-plus";
import type { AppContext, PropType } from "vue";

ElInput.props = {
	...ElInput.props,
	/**
	 * 默认显示统计字数
	 * @description word count
	 */
	showWordLimit: {
		type: Boolean,
		default: true,
	},
};

ElInputNumber.props = {
	...ElInputNumber.props,
	/**
	 * 默认不使用控制按钮
	 * @description whether to enable the control buttons
	 */
	controls: {
		type: Boolean,
		default: false,
	},
};

ElDialog.props = {
	...ElDialog.props,
	/**
	 * 默认水平垂直居中
	 * @description whether to align the dialog both horizontally and vertically
	 * */
	alignCenter: {
		type: Boolean,
		default: true,
	},
	/**
	 * 默认拖拽
	 * @description enable dragging feature for Dialog
	 */
	draggable: {
		type: Boolean,
		default: true,
	},
};

ElForm.props = {
	...ElForm.props,
	/** @description Width of label, e.g. `'50px'`. All its direct child form items will inherit this value. `auto` is supported. */
	labelWidth: {
		type: [String, Number],
		default: "auto",
	},
	/** @description Suffix of the label. */
	labelSuffix: {
		type: String,
		default: "：",
	},
	/** @description When validation fails, scroll to the first error form entry. */
	scrollToError: {
		type: Boolean,
		default: true,
	},
};

ElSelect.props = {
	...ElSelect.props,
	/** @description displayed text while loading data from server, default is 'Loading' */
	loadingText: {
		type: String,
		default: "加载中...",
	},
	/** @description displayed text when no data matches the filtering query, you can also use slot `empty`, default is 'No matching data' */
	noMatchText: {
		type: String,
		default: "暂无匹配的数据",
	},
	/** @description displayed text when there is no options, you can also use slot `empty`, default is 'No data' */
	noDataText: {
		type: String,
		default: "暂无数据",
	},
	/**
	 * 默认按文字形式展示
	 * @description whether to collapse tags to a text when multiple selecting
	 */
	collapseTags: {
		type: Boolean,
		default: true,
	},
	/**
	 * 默认显示所有选中的标签
	 * @description whether show all selected tags when mouse hover text of collapse-tags. To use this, `collapse-tags` must be true
	 */
	collapseTagsTooltip: {
		type: Boolean,
		default: true,
	},
};

ElTree.props = {
	...ElTree.props,
	/**
	 * 默认展开所有节点
	 * @description 是否默认展开所有节点
	 */
	defaultExpandAll: {
		type: Boolean,
		default: true,
	},
	/**
	 * 默认点击时选中节点
	 * @description 是否在点击节点的时候选中节点
	 */
	checkOnClickNode: {
		type: Boolean,
		default: true,
	},
	/**
	 * 默认高亮选中节点
	 * @description 是否高亮当前选中节点
	 */
	highlightCurrent: {
		type: Boolean,
		default: true,
	},
};

ElTreeSelect.props = {
	...ElTreeSelect.props,
	/** @description displayed text while loading data from server, default is 'Loading' */
	loadingText: {
		type: String,
		default: "加载中...",
	},
	/** @description displayed text when no data matches the filtering query, you can also use slot `empty`, default is 'No matching data' */
	noMatchText: {
		type: String,
		default: "暂无匹配的数据",
	},
	/** @description displayed text when there is no options, you can also use slot `empty`, default is 'No data' */
	noDataText: {
		type: String,
		default: "暂无数据",
	},
	/**
	 * 默认按文字形式展示
	 * @description whether to collapse tags to a text when multiple selecting
	 */
	collapseTags: {
		type: Boolean,
		default: true,
	},
	/**
	 * 默认显示所有选中的标签
	 * @description whether show all selected tags when mouse hover text of collapse-tags. To use this, `collapse-tags` must be true
	 */
	collapseTagsTooltip: {
		type: Boolean,
		default: true,
	},
	/**
	 * 默认展开所有节点
	 * @description 是否默认展开所有节点
	 */
	defaultExpandAll: {
		type: Boolean,
		default: true,
	},
	/**
	 * 默认点击时选中节点
	 * @description 是否在点击节点的时候选中节点
	 */
	checkOnClickNode: {
		type: Boolean,
		default: true,
	},
	/**
	 * 默认高亮选中节点
	 * @description 是否高亮当前选中节点
	 */
	highlightCurrent: {
		type: Boolean,
		default: true,
	},
	/**
	 * 默认点击节点不展开或收缩节点
	 * @description 是否在点击节点的时候展开或者收缩节点， 默认值为 true，如果为 false，则只有点箭头图标的时候才会展开或者收缩节点。
	 */
	expandOnClickNode: Boolean,
};

ElTable.props = {
	...ElTable.props,
	/**
	 * 默认显示边框
	 * @description whether Table has vertical border
	 */
	border: {
		type: Boolean,
		default: true,
	},
	/**
	 * 默认高亮当前行
	 * @description whether current row is highlighted
	 */
	highlightCurrentRow: {
		type: Boolean,
		default: true,
	},
	/**
	 * 默认行Key为 "id"
	 * @description key of row data, used for optimizing rendering. Required if `reserve-selection` is on or display tree data. When its type is String, multi-level access is supported, e.g. `user.info.id`, but `user.info[0].id` is not supported, in which case `Function` should be used
	 */
	rowKey: {
		type: [String, Function] as PropType<TableProps<any>["rowKey"]>,
		default: "id",
	},
};

const elMessageBox = (
	type: "alert" | "confirm" | "prompt",
	message: ElMessageBoxOptions["message"],
	options?: ElMessageBoxOptions,
	appContext?: AppContext | null
): Promise<MessageBoxData> => {
	options = options ?? {};
	if (!options?.title) {
		// 默认提示
		options.title = "温馨提示";
	}
	// 默认拖拽
	options.draggable = true;

	return ElMessageBox(
		Object.assign(
			{
				message,
			},
			options,
			{
				boxType: type,
			}
		)
	);
};

type MESSAGE_BOX_TYPE = "alert" | "confirm" | "prompt";
const MESSAGE_BOX_DEFAULT_OPTS: Record<MESSAGE_BOX_TYPE, Partial<ElMessageBoxOptions>> = {
	alert: { closeOnPressEscape: false, closeOnClickModal: false },
	confirm: { showCancelButton: true },
	prompt: { showCancelButton: true, showInput: true },
};

ElMessageBox.alert = (
	message: ElMessageBoxOptions["message"],
	titleOrOptions?: string | ElMessageBoxOptions,
	options?: ElMessageBoxOptions,
	appContext?: AppContext | null
): Promise<MessageBoxData> =>
	isString(titleOrOptions)
		? elMessageBox("alert", message, Object.assign({ title: titleOrOptions, ...MESSAGE_BOX_DEFAULT_OPTS["alert"] }, options), appContext)
		: elMessageBox("alert", message, Object.assign(titleOrOptions, MESSAGE_BOX_DEFAULT_OPTS["alert"], options), options as AppContext);

ElMessageBox.prompt = (
	message: ElMessageBoxOptions["message"],
	titleOrOptions?: string | ElMessageBoxOptions,
	options?: ElMessageBoxOptions,
	appContext?: AppContext | null
): Promise<MessageBoxData> =>
	isString(titleOrOptions)
		? elMessageBox("prompt", message, Object.assign({ title: titleOrOptions, ...MESSAGE_BOX_DEFAULT_OPTS["prompt"] }, options), appContext)
		: elMessageBox("prompt", message, Object.assign(titleOrOptions, MESSAGE_BOX_DEFAULT_OPTS["prompt"], options), options as AppContext);

ElMessageBox.confirm = (
	message: ElMessageBoxOptions["message"],
	titleOrOptions?: string | ElMessageBoxOptions,
	options?: AppContext | ElMessageBoxOptions,
	appContext?: AppContext | null
): Promise<MessageBoxData> =>
	isString(titleOrOptions)
		? elMessageBox("confirm", message, Object.assign({ title: titleOrOptions, ...MESSAGE_BOX_DEFAULT_OPTS["confirm"] }, options), appContext)
		: elMessageBox("confirm", message, Object.assign(titleOrOptions, MESSAGE_BOX_DEFAULT_OPTS["confirm"], options), options as AppContext);
